home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / hurd / hurdioctl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-30  |  5.9 KB  |  250 lines

  1. /* ioctl commands which must be done in the C library.
  2. Copyright (C) 1994 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. #include <hurd.h>
  21. #include <hurd/fd.h>
  22. #include <sys/ioctl.h>
  23. #include <gnu-stabs.h>
  24.  
  25.  
  26. /* Symbol set of ioctl handler lists.
  27.    This must be uninitialized for ld to use it for the set.  */
  28. struct handler_set
  29.   {
  30.     size_t n;
  31.     struct ioctl_handler *v[0];
  32.   };
  33. struct handler_set _hurd_ioctl_handler_lists;
  34.  
  35. /* This definition is here (and initialized!) so that when __ioctl refers
  36.    to it, we will link in fionread et al (below).  */
  37. struct handler_set *const _hurd_ioctl_handlers = &_hurd_ioctl_handler_lists;
  38.  
  39. #include <fcntl.h>
  40.  
  41. /* Find out how many bytes may be read from FD without blocking.  */
  42.  
  43. static int
  44. fioctl (int fd,
  45.     int request,
  46.     int *arg)
  47. {
  48.   error_t err;
  49.  
  50.   *(volatile int *) arg = *arg;
  51.  
  52.   switch (request)
  53.     {
  54.     default:
  55.       err = EGRATUITOUS;
  56.       break;
  57.  
  58.     case FIONREAD:
  59.       err = HURD_DPORT_USE (fd, __io_readable (port, arg));
  60.       break;
  61.  
  62.     case FIONBIO:
  63.       err = HURD_DPORT_USE (fd, (*arg ?
  64.                  __io_set_some_openmodes :
  65.                  __io_clear_some_openmodes)
  66.                 (port, O_NONBLOCK));
  67.       break;
  68.  
  69.     case FIOASYNC:
  70.       err = HURD_DPORT_USE (fd, (*arg ?
  71.                  __io_set_some_openmodes :
  72.                  __io_clear_some_openmodes)
  73.                 (port, O_ASYNC));
  74.       break;
  75.  
  76.     case FIOSETOWN:
  77.       err = HURD_DPORT_USE (fd, __io_mod_owner (port, *arg));
  78.       break;
  79.  
  80.     case FIOGETOWN:
  81.       err = HURD_DPORT_USE (fd, __io_get_owner (port, arg));
  82.       break;
  83.     }
  84.  
  85.   return err ? __hurd_fail (err) : 0;
  86. }
  87.  
  88. _HURD_HANDLE_IOCTLS (fioctl, FIOGETOWN, FIONREAD);
  89.  
  90.  
  91. static int
  92. fioclex (int fd,
  93.      int request)
  94. {
  95.   int flag;
  96.  
  97.   switch (request)
  98.     {
  99.     default:
  100.       return __hurd_fail (EGRATUITOUS);
  101.     case FIOCLEX:
  102.       flag = FD_CLOEXEC;
  103.       break;
  104.     case FIONCLEX:
  105.       flag = 0;
  106.       break;
  107.     }
  108.  
  109.   return __fcntl (fd, F_SETFD, flag);
  110. }
  111. _HURD_HANDLE_IOCTLS (fioclex, FIOCLEX, FIONCLEX);
  112.  
  113. #include <hurd/term.h>
  114.  
  115. static void
  116. rectty_dtable (mach_port_t cttyid)
  117. {
  118.   int i;
  119.   
  120.   HURD_CRITICAL_BEGIN;
  121.   __mutex_lock (&_hurd_dtable_lock);
  122.  
  123.   for (i = 0; i < _hurd_dtablesize; ++i)
  124.     {
  125.       struct hurd_fd *const d = _hurd_dtable[i];
  126.       mach_port_t newctty;
  127.  
  128.       if (d == NULL)
  129.     /* Nothing to do for an unused descriptor cell.  */
  130.     continue;
  131.  
  132.       if (cttyid == MACH_PORT_NULL)
  133.     /* We now have no controlling tty at all.  */
  134.     newctty = MACH_PORT_NULL;
  135.       else
  136.     HURD_PORT_USE (&d->port,
  137.                ({ mach_port_t id;
  138.               /* Get the io object's cttyid port.  */
  139.               if (! __term_getctty (port, &id))
  140.                 {
  141.                   if (id == cttyid && /* Is it ours?  */
  142.                   /* Get the ctty io port.  */
  143.                   __term_open_ctty (port,
  144.                             _hurd_pid, _hurd_pgrp,
  145.                             &newctty))
  146.                 /* XXX it is our ctty but the call failed? */
  147.                 newctty = MACH_PORT_NULL;
  148.                   __mach_port_deallocate
  149.                 (__mach_task_self (), (mach_port_t) id);
  150.                 }
  151.               else
  152.                 newctty = MACH_PORT_NULL;
  153.               0;
  154.             }));
  155.  
  156.       /* Install the new ctty port.  */
  157.       _hurd_port_set (&d->ctty, newctty);
  158.     }
  159.  
  160.   __mutex_unlock (&_hurd_dtable_lock);
  161.   HURD_CRITICAL_END;
  162. }
  163.  
  164.  
  165. /* Called when we have received a message saying to use a new ctty ID port.  */
  166.  
  167. error_t
  168. _hurd_setcttyid (mach_port_t cttyid)
  169. {
  170.   error_t err;
  171.  
  172.   if (cttyid != MACH_PORT_NULL)
  173.     {
  174.       /* Give the new send right a user reference.
  175.      This is a good way to check that it is valid.  */
  176.       if (err = __mach_port_mod_refs (__mach_task_self (), cttyid,
  177.                       MACH_PORT_RIGHT_SEND, 1))
  178.     return err;
  179.     }
  180.  
  181.   /* Install the port, consuming the reference we just created.  */
  182.   _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], cttyid);
  183.  
  184.   /* Reset all the ctty ports in all the descriptors.  */
  185.   __USEPORT (CTTYID, (rectty_dtable (cttyid), 0));
  186.  
  187.   return 0;
  188. }
  189.  
  190.  
  191. /* Make FD be the controlling terminal.
  192.    This function is called for `ioctl (fd, TCIOSCTTY)'.  */
  193.  
  194. static int
  195. tiocsctty (int fd,
  196.        int request)        /* Always TIOCSCTTY.  */
  197. {
  198.   mach_port_t cttyid;
  199.   error_t err;
  200.  
  201.   /* Get FD's cttyid port, unless it is already ours.  */
  202.   err = HURD_DPORT_USE (fd, ctty != MACH_PORT_NULL ? EADDRINUSE :
  203.             __term_getctty (port, &cttyid));
  204.   if (err == EADDRINUSE)
  205.     /* FD is already the ctty.  Nothing to do.  */
  206.     return 0;
  207.   else if (err)
  208.     return __hurd_fail (err);
  209.  
  210.   /* Make it our own.  */
  211.   _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], cttyid);
  212.  
  213.   /* Reset all the ctty ports in all the descriptors.  */
  214.   __USEPORT (CTTYID, (rectty_dtable (cttyid), 0));
  215.  
  216.   return 0;
  217. }
  218. _HURD_HANDLE_IOCTL (tiocsctty, TIOCSCTTY);
  219.  
  220. /* Dissociate from the controlling terminal.  */
  221.  
  222. static int
  223. tiocnotty (int fd,
  224.        int request)        /* Always TIOCNOTTY.  */
  225. {
  226.   mach_port_t fd_cttyid;
  227.   error_t err;
  228.  
  229.   if (err = HURD_DPORT_USE (fd, __term_getctty (port, &fd_cttyid)))
  230.     return __hurd_fail (err);
  231.  
  232.   if (__USEPORT (CTTYID, port != fd_cttyid))
  233.     err = EINVAL;
  234.  
  235.   __mach_port_deallocate (__mach_task_self (), fd_cttyid);
  236.  
  237.   if (err)
  238.     return __hurd_fail (err);
  239.  
  240.   /* Clear our cttyid port cell.  */
  241.   _hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], MACH_PORT_NULL);
  242.  
  243.   /* Reset all the ctty ports in all the descriptors.  */
  244.                 
  245.   __USEPORT (CTTYID, (rectty_dtable (MACH_PORT_NULL), 0));
  246.  
  247.   return 0;
  248. }
  249. _HURD_HANDLE_IOCTL (tiocnotty, TIOCNOTTY);
  250.